package shujia.day18;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

/*
    反射获取成员方法并使用
 */
public class ClassDemo4 {
    public static void main(String[] args) throws Exception {
        Class<?> studentClass = Class.forName("shujia.day18.Student");

        //public Method getMethod(String name, Class<?>... parameterTypes) 获取某一个公共的成员方法
        // 获取一个无参的方法，方法名叫做fun1
        Method fun1 = studentClass.getMethod("fun1");
        System.out.println("fun1: " + fun1 );
        // 获取一个有一个参数为String类型的方法，方法名叫做fun2
        Method fun2 = studentClass.getMethod("fun2", String.class);
        System.out.println("fun2: " + fun2);
//        Method fun3 = studentClass.getMethod("fun3");
//        System.out.println("fun3: " + fun3);

        //public Method getDeclaredMethod(String name, Class<?>... parameterTypes) 获取任意权限修饰符的成员方法
        Method fun3 = studentClass.getDeclaredMethod("fun3");
        System.out.println("fun3: " + fun3);

        //根据参数的类型和方法名获取对应的方法，将其封装成Method对象进行返回
        Method fun4 = studentClass.getDeclaredMethod("fun4", String.class);
        System.out.println("fun4: " + fun4);


        //如何使用获取到的成员方法
        //之前写代码的思想：对象是固定的，调用对象中的某一个方法
        //反射中的思想：方法是固定的，是哪一个对象的该方法
        Constructor<?> c1 = studentClass.getDeclaredConstructor();
        c1.setAccessible(true);
        Student s = (Student) c1.newInstance();
        // 调用对象s中的fun1方法
        //Method类中有一个方法invoke'
        //public Object invoke(Object obj, Object... args)
        Object o = fun1.invoke(s);
        System.out.println(o);

        //调用对象s中的fun4方法
        fun4.setAccessible(true);
        fun4.invoke(s, "shujia");
        System.out.println("--------------------------------------------");
        //getMethods 获取自己本类或父类所有的public修饰的方法
        Method[] methods = studentClass.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }

        System.out.println("------------------------------------------");
        //getDeclaredMethods 只能获取本类中的所有方法，父亲的不管
        Method[] declaredMethods = studentClass.getDeclaredMethods();
        for (Method method : declaredMethods) {
            System.out.println(method);
        }
    }
}
